package kr.co.inger.hotwind.utils; import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.lang.ObjectUtils; import org.reflections.Reflections; import org.reflections.scanners.ResourcesScanner; import org.reflections.scanners.SubTypesScanner; import org.reflections.scanners.TypeAnnotationsScanner; import org.reflections.util.ClasspathHelper; import org.reflections.util.ConfigurationBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Strings; public class ClassUtils { private static Logger logger = LoggerFactory.getLogger(ClassUtils.class); /** 특정 패키지 이하의, 특정 어노테이션 지정된 클래스들 찾기. */ public static Set<Class<?>> findAnnotatedClasses(final String rootPackage, final Class<? extends Annotation> klassAnnotation) { Reflections reflections = new Reflections(new ConfigurationBuilder() .addUrls(ClasspathHelper.forPackage(rootPackage)).setScanners( new ResourcesScanner(), new TypeAnnotationsScanner(), new SubTypesScanner())); Set<Class<?>> annotatedKlasses = reflections .getTypesAnnotatedWith(klassAnnotation); logger.info(ObjectUtils.toString(annotatedKlasses)); return annotatedKlasses; } public static Set<Class<?>> findClassesByPackagesAndAnnotations( List<Object> packageNames, List<Object> annotationFqns) { // Set<Class<?>> result = new HashSet<Class<?>>(); // for (Object packageNameObj : packageNames) { if (Strings.isNullOrEmpty((String) packageNameObj)) continue; final String pakcageName = ObjectUtils.toString(packageNameObj); for (Object annotationFqnObj : annotationFqns) { final String annotationFqn = ObjectUtils .toString(annotationFqnObj); // Class<? extends Annotation> klassAnnotation = null; try { klassAnnotation = (Class<? extends Annotation>) Class .forName(annotationFqn); } catch (ClassNotFoundException e) { logger.warn(String.format("%s class-get fail! -- skip", annotationFqn), e); } if (klassAnnotation != null) { final Set<Class<?>> classes = findAnnotatedClasses( pakcageName, klassAnnotation); result.addAll(classes); } } } // return result; } /** * 모든 Jersey 리소스 클래스들을 등록. 실제로 모듈로서 이들을 활용하지 않고(인스턴스로 만들지도 않음.), 단지 바인딩만 하여 * 이후 요청에 있어서 처리에만 활용한다. * * @param classFqns */ public static Set<Class<?>> findClassesByFqns(final List<Object> classFqns) { Set<Class<?>> result = new HashSet<Class<?>>(); for (final Object classFqn : classFqns) { try { Class klass = (Class) Class.forName((String) classFqn); result.add(klass); } catch (Exception exc) { logger.warn(String.format("find-class fail, skip -- fqn=[%s]", classFqn), exc); } } return result; } }